+++ /dev/null
-Author: Joerg Riesmeier <dicom@jriesmeier.com>
-Forwarded: https://git.dcmtk.org/?p=dcmtk.git;a=commit;h=89a6e399f1e17d08a8bc8cdaa05b2ac9a50cd4f6
-Bug-Debian: https://bugs.debian.org/1093043
-Reviewed-By: Étienne Mollier <emollier@debian.org>
-Last-Update: 2025-01-18
-Description: Fixed issue rendering invalid monochrome image.
- Fixed issue when rendering an invalid monochrome DICOM image where the
- number of pixels stored does not match the expected number of pixels.
- If the stored number is less than the expected number, the rest of the
- pixel matrix for the intermediate representation was always filled with
- the value 0. Under certain, very rare conditions, this could result in
- memory problems reported by an Address Sanitizer (ASAN). Now, the rest
- of the matrix is filled with the smallest possible value for the image.
- .
- Thanks to Emmanuel Tacheau from the Cisco Talos team
- <vulndiscovery@external.cisco.com> for the original report, the sample
- file (PoC) and further details. See TALOS-2024-2122 and CVE-2024-47796.
-
---- dcmtk.orig/dcmimgle/include/dcmtk/dcmimgle/dimoipxt.h
-+++ dcmtk/dcmimgle/include/dcmtk/dcmimgle/dimoipxt.h
-@@ -72,9 +72,9 @@
- rescale(pixel); // "copy" or reference pixel data
- this->determineMinMax(OFstatic_cast(T3, this->Modality->getMinValue()), OFstatic_cast(T3, this->Modality->getMaxValue()));
- }
-- /* erase empty part of the buffer (= blacken the background) */
-+ /* erase empty part of the buffer (= fill the background with the smallest possible value) */
- if ((this->Data != NULL) && (this->InputCount < this->Count))
-- OFBitmanipTemplate<T3>::zeroMem(this->Data + this->InputCount, this->Count - this->InputCount);
-+ OFBitmanipTemplate<T3>::setMem(this->Data + this->InputCount, OFstatic_cast(T3, this->Modality->getAbsMinimum()), this->Count - this->InputCount);
- }
- }
-
+++ /dev/null
-Author: Joerg Riesmeier <dicom@jriesmeier.com>
-Forwarded: https://git.dcmtk.org/?p=dcmtk.git;a=commit;h=03e851b0586d05057c3268988e180ffb426b2e03
-Bug-Debian: https://bugs.debian.org/1093047
-Reviewed-By: Étienne Mollier <emollier@debian.org>
-Last-Update: 2025-01-18
-Description: Added check to make sure: HighBit < BitsAllocated.
- Added check to the image preprocessing to make sure that the value of
- HighBit is always less than the value of BitsAllocated. Before, this
- missing check could lead to memory corruption if an invalid combination
- of values was retrieved from a malformed DICOM dataset.
- .
- Thanks to Emmanuel Tacheau from the Cisco Talos team
- <vulndiscovery@external.cisco.com> for the report, sample file (PoC)
- and detailed analysis. See TALOS-2024-2121 and CVE-2024-52333.
-
---- dcmtk.orig/dcmimgle/libsrc/diimage.cc
-+++ dcmtk/dcmimgle/libsrc/diimage.cc
-@@ -1,6 +1,6 @@
- /*
- *
-- * Copyright (C) 1996-2024, OFFIS e.V.
-+ * Copyright (C) 1996-2025, OFFIS e.V.
- * All rights reserved. See COPYRIGHT file for details.
- *
- * This software and supporting documentation were developed by
-@@ -549,12 +549,18 @@
- {
- const unsigned long fsize = OFstatic_cast(unsigned long, Rows) * OFstatic_cast(unsigned long, Columns) *
- OFstatic_cast(unsigned long, SamplesPerPixel);
-- if ((BitsAllocated < 1) || (BitsStored < 1) || (BitsAllocated < BitsStored) ||
-- (BitsStored > OFstatic_cast(Uint16, HighBit + 1)))
-+ if ((BitsAllocated < 1) || (BitsStored < 1))
- {
- ImageStatus = EIS_InvalidValue;
-- DCMIMGLE_ERROR("invalid values for 'BitsAllocated' (" << BitsAllocated << "), "
-- << "'BitsStored' (" << BitsStored << ") and/or 'HighBit' (" << HighBit << ")");
-+ DCMIMGLE_ERROR("invalid value(s) for 'BitsAllocated' (" << BitsAllocated << "), "
-+ << "and/or 'BitsStored' (" << BitsStored << ")");
-+ return;
-+ }
-+ else if ((BitsAllocated < BitsStored) || (BitsAllocated <= HighBit) || ((BitsStored - 1) > HighBit))
-+ {
-+ ImageStatus = EIS_InvalidValue;
-+ DCMIMGLE_ERROR("invalid combination of values for 'BitsAllocated' (" << BitsAllocated << "), "
-+ << "'BitsStored' (" << BitsStored << ") and 'HighBit' (" << HighBit << ")");
- return;
- }
- else if ((evr == EVR_OB) && (BitsStored <= 8))
+++ /dev/null
-commit bffa3e9116abb7038b432443f16b1bd390e80245
-Author: Marco Eichelberg <eichelberg@offis.de>
-Date: Thu Jan 23 15:51:21 2025 +0100
-
- Fixed issue with invalid RLE compressed DICOM images.
-
- Fixed issue when processing an RLE compressed image where the RLE header
- contains an invalid stripe size.
-
- Thanks to Ding zhengzheng <xiaozheng.ding399@gmail.com> for the report
- and the sample file (PoC).
-
---- dcmtk.orig/dcmdata/libsrc/dcrleccd.cc
-+++ dcmtk/dcmdata/libsrc/dcrleccd.cc
-@@ -1,6 +1,6 @@
- /*
- *
-- * Copyright (C) 2002-2024, OFFIS e.V.
-+ * Copyright (C) 2002-2025, OFFIS e.V.
- * All rights reserved. See COPYRIGHT file for details.
- *
- * This software and supporting documentation were developed by
-@@ -348,6 +348,12 @@
- } /* while */
-
- // last fragment for this RLE stripe
-+ if (inputBytes + byteOffset > fragmentLength)
-+ {
-+ DCMDATA_ERROR("stream size in RLE header is wrong");
-+ inputBytes = fragmentLength-byteOffset;
-+ }
-+
- result = rledecoder.decompress(rleData + byteOffset, OFstatic_cast(size_t, inputBytes));
-
- // special handling for zero pad byte at the end of the RLE stream
+++ /dev/null
-commit 1d205bcd307164c99e0d4bbf412110372658d847
-Author: Joerg Riesmeier <dicom@jriesmeier.com>
-Date: Tue Jan 21 11:12:28 2025 +0100
-
- Fixed another issue with invalid DICOM images.
-
- Fixed issue when processing an invalid DICOM image where the number of
- pixels stored does not match the expected number of pixels (too less)
- and the combination of BitsAllocated and BitsStored is really unusual
- (e.g. 1 bit stored, but 52 bits allocated). In cases where the last
- pixel (e.g. a single bit) does not fit into the buffer of the input
- pixel data, a buffer overflow occurred on the heap. Now, the last entry
- of the buffer is filled with the smallest possible value (e.g. 0 in case
- of unsigned data).
-
- Thanks to Ding zhengzheng <xiaozheng.ding399@gmail.com> for the report
- and the sample file (PoC).
-
---- dcmtk.orig/dcmimgle/include/dcmtk/dcmimgle/diinpxt.h
-+++ dcmtk/dcmimgle/include/dcmtk/dcmimgle/diinpxt.h
-@@ -643,6 +643,13 @@
- skip -= times * bitsof_T1;
- }
- }
-+ /* fill the remaining entry (if any) with the smallest value that is possible */
-+ if (q < Data + Count)
-+ {
-+ DCMIMGLE_TRACE("not enough data, filling last entry of input buffer with value = " << getAbsMinimum());
-+ *q = OFstatic_cast(T2, getAbsMinimum());
-+ }
-+
- }
- } else
- DCMIMGLE_DEBUG("cannot allocate memory buffer for 'Data' in DiInputPixelTemplate::convert()");
+++ /dev/null
-commit 410ffe2019b9db6a8f4036daac742a6f5e4d36c2
-Author: Joerg Riesmeier <dicom@jriesmeier.com>
-Date: Fri Jan 17 17:53:50 2025 +0100
-
- Fixed another issue with invalid mono images.
-
- Fixed issue when rendering an invalid monochrome DICOM image where the
- number of pixels stored does not match the expected number of pixels.
- In this case, only a single pixel is processed, but the pixel matrix is
- much larger. Filling the rest of the pixel matrix with the smallest
- possible value for the image is not working because of an optimized
- memory usage (value would be out of range). Now, the pixel value to be
- used is double-checked before it is actually filled into the "background"
- of the image.
-
- Thanks to Ding zhengzheng <xiaozheng.ding399@gmail.com> for the report
- and the sample file (PoC).
-
-diff --git a/dcmimgle/include/dcmtk/dcmimgle/dimoipxt.h b/dcmimgle/include/dcmtk/dcmimgle/dimoipxt.h
-index 50389a540..f67967310 100644
---- a/dcmimgle/include/dcmtk/dcmimgle/dimoipxt.h
-+++ b/dcmimgle/include/dcmtk/dcmimgle/dimoipxt.h
-@@ -28,6 +28,7 @@
- #include "dcmtk/ofstd/ofbmanip.h"
- #include "dcmtk/ofstd/ofcast.h"
- #include "dcmtk/ofstd/ofdiag.h" /* for DCMTK_DIAGNOSTIC macros */
-+#include "dcmtk/ofstd/oflimits.h" /* for OFnumeric_limits<> */
-
- #include "dcmtk/dcmimgle/dimopxt.h"
- #include "dcmtk/dcmimgle/diinpx.h"
-@@ -72,9 +73,16 @@ class DiMonoInputPixelTemplate
- rescale(pixel); // "copy" or reference pixel data
- this->determineMinMax(OFstatic_cast(T3, this->Modality->getMinValue()), OFstatic_cast(T3, this->Modality->getMaxValue()));
- }
-- /* erase empty part of the buffer (= fill the background with the smallest possible value) */
-+ /* erase empty part of the buffer */
- if ((this->Data != NULL) && (this->InputCount < this->Count))
-- OFBitmanipTemplate<T3>::setMem(this->Data + this->InputCount, OFstatic_cast(T3, this->Modality->getAbsMinimum()), this->Count - this->InputCount);
-+ {
-+ /* that means, fill the background with the smallest value that is possible */
-+ const T3 minOut = OFnumeric_limits<T3>::min();
-+ const T3 background = (this->Modality->getAbsMinimum() < OFstatic_cast(double, minOut)) ? minOut : OFstatic_cast(T3, this->Modality->getAbsMinimum());
-+ const size_t count = (this->Count - this->InputCount);
-+ DCMIMGLE_DEBUG("filing empty part of the intermediate pixel data (" << count << " pixels) with value = " << OFstatic_cast(double, background));
-+ OFBitmanipTemplate<T3>::setMem(this->Data + this->InputCount, background, count);
-+ }
- }
- }
-
+++ /dev/null
-From: Marco Eichelberg <eichelberg@offis.de>
-Date: Mon, 3 Mar 2025 11:33:18 +0000 (+0100)
-Subject: Fixed segfault in JPEG-LS decoder.
-X-Git-Url: http://git.dcmtk.org/?p=dcmtk.git;a=commitdiff_plain;h=3239a791542e1ea433d23aaa9e0a05a532ffabff;hp=92fc86e9e8d0808880bcc82e25982b2a61323cb8
-
-Fixed segfault in JPEG-LS decoder.
-
-Fixed a bug in the JPEG-LS decoder that led to a segmentation fault if invalid
-input data was processed, due to insufficient validation of input data.
-
-Thanks to Ding zhengzheng <xiaozheng.ding399@gmail.com> for the report
-and the sample file (PoC).
-
-This closes DCMTK issue #1155.
----
-
-diff --git a/dcmjpls/libcharls/scan.h b/dcmjpls/libcharls/scan.h
-index b4dea20d8..f13098104 100644
---- a/dcmjpls/libcharls/scan.h
-+++ b/dcmjpls/libcharls/scan.h
-@@ -1,6 +1,6 @@
--//
--// (C) Jan de Vaan 2007-2010, all rights reserved. See the accompanying "License.txt" for licensed use.
--//
-+//
-+// (C) Jan de Vaan 2007-2010, all rights reserved. See the accompanying "License.txt" for licensed use.
-+//
-
- #ifndef CHARLS_SCAN
- #define CHARLS_SCAN
-@@ -11,7 +11,7 @@
-
- #include "lokuptbl.h"
-
--// This file contains the code for handling a "scan". Usually an image is encoded as a single scan.
-+// This file contains the code for handling a "scan". Usually an image is encoded as a single scan.
-
- #include DCMTK_DIAGNOSTIC_IGNORE_CONST_EXPRESSION_WARNING
-
-@@ -21,10 +21,10 @@ extern OFVector<signed char> rgquant10Ll;
- extern OFVector<signed char> rgquant12Ll;
- extern OFVector<signed char> rgquant16Ll;
- //
--// Apply
-+// Apply
- //
- inlinehint LONG ApplySign(LONG i, LONG sign)
--{ return (sign ^ i) - sign; }
-+{ return (sign ^ i) - sign; }
-
-
-
-@@ -58,20 +58,20 @@ inlinehint LONG GetPredictedValue(LONG Ra, LONG Rb, LONG Rc)
-
- inlinehint LONG GetPredictedValue(LONG Ra, LONG Rb, LONG Rc)
- {
-- // sign trick reduces the number of if statements (branches)
-+ // sign trick reduces the number of if statements (branches)
- LONG sgn = BitWiseSign(Rb - Ra);
-
-- // is Ra between Rc and Rb?
-+ // is Ra between Rc and Rb?
- if ((sgn ^ (Rc - Ra)) < 0)
- {
- return Rb;
-- }
-+ }
- else if ((sgn ^ (Rb - Rc)) < 0)
- {
- return Ra;
- }
-
-- // default case, valid if Rc element of [Ra,Rb]
-+ // default case, valid if Rc element of [Ra,Rb]
- return Ra + Rb - Rc;
- }
-
-@@ -110,7 +110,7 @@ public:
-
- public:
-
-- JlsCodec(const TRAITS& inTraits, const JlsParameters& info) : STRATEGY(info),
-+ JlsCodec(const TRAITS& inTraits, const JlsParameters& info) : STRATEGY(info),
- traits(inTraits),
- _rect(),
- _width(0),
-@@ -120,13 +120,13 @@ public:
- _RUNindex(0),
- _pquant(0),
- _bCompare(0)
--
-+
- {
- if (Info().ilv == ILV_NONE)
- {
- Info().components = 1;
- }
-- }
-+ }
-
-
- void SetPresets(const JlsCustomParameters& presets)
-@@ -135,9 +135,9 @@ public:
-
- InitParams(presets.T1 != 0 ? presets.T1 : presetDefault.T1,
- presets.T2 != 0 ? presets.T2 : presetDefault.T2,
-- presets.T3 != 0 ? presets.T3 : presetDefault.T3,
-+ presets.T3 != 0 ? presets.T3 : presetDefault.T3,
- presets.RESET != 0 ? presets.RESET : presetDefault.RESET);
-- }
-+ }
-
-
- bool IsInterleaved()
-@@ -155,13 +155,13 @@ public:
-
- signed char QuantizeGratientOrg(LONG Di);
- inlinehint LONG QuantizeGratient(LONG Di)
-- {
-+ {
- ASSERT(QuantizeGratientOrg(Di) == *(_pquant + Di));
-- return *(_pquant + Di);
-+ return *(_pquant + Di);
- }
-
- void InitQuantizationLUT();
--
-+
- LONG DecodeValue(LONG k, LONG limit, LONG qbpp);
- inlinehint void EncodeMappedValue(LONG k, LONG mappedError, LONG limit);
-
-@@ -216,27 +216,27 @@ public:
- {
- LONG sign = BitWiseSign(Qs);
- JlsContext& ctx = _contexts[ApplySign(Qs, sign)];
-- LONG k = ctx.GetGolomb();
-- LONG Px = traits.CorrectPrediction(pred + ApplySign(ctx.C, sign));
-+ LONG k = ctx.GetGolomb();
-+ LONG Px = traits.CorrectPrediction(pred + ApplySign(ctx.C, sign));
-
- LONG ErrVal;
- const Code& code = decodingTables[k].Get(STRATEGY::PeekByte());
- if (code.GetLength() != 0)
- {
- STRATEGY::Skip(code.GetLength());
-- ErrVal = code.GetValue();
-+ ErrVal = code.GetValue();
- ASSERT(ABS(ErrVal) < 65535);
- }
- else
- {
-- ErrVal = UnMapErrVal(DecodeValue(k, traits.LIMIT, traits.qbpp));
-+ ErrVal = UnMapErrVal(DecodeValue(k, traits.LIMIT, traits.qbpp));
- if (ABS(ErrVal) > 65535)
- throw JlsException(InvalidCompressedData);
-- }
-+ }
- ErrVal = ErrVal ^ ((traits.NEAR == 0) ? ctx.GetErrorCorrection(k) : 0);
-- ctx.UpdateVariables(ErrVal, traits.NEAR, traits.RESET);
-+ ctx.UpdateVariables(ErrVal, traits.NEAR, traits.RESET);
- ErrVal = ApplySign(ErrVal, sign);
-- return traits.ComputeReconstructedSample(Px, ErrVal);
-+ return traits.ComputeReconstructedSample(Px, ErrVal);
- }
-
-
-@@ -245,7 +245,7 @@ public:
- LONG sign = BitWiseSign(Qs);
- JlsContext& ctx = _contexts[ApplySign(Qs, sign)];
- LONG k = ctx.GetGolomb();
-- LONG Px = traits.CorrectPrediction(pred + ApplySign(ctx.C, sign));
-+ LONG Px = traits.CorrectPrediction(pred + ApplySign(ctx.C, sign));
-
- LONG ErrVal = traits.ComputeErrVal(ApplySign(x - Px, sign));
-
-@@ -270,16 +270,16 @@ public:
- size_t DecodeScan(void* rawData, const JlsRect& size, BYTE **buf, size_t *buf_size, size_t offset, bool bCompare);
-
- protected:
-- // codec parameters
-+ // codec parameters
- TRAITS traits;
- JlsRect _rect;
- int _width;
-- LONG T1;
-+ LONG T1;
- LONG T2;
-- LONG T3;
-+ LONG T3;
-
- // compression context
-- JlsContext _contexts[365];
-+ JlsContext _contexts[365];
- CContextRunMode _contextRunmode[2];
- LONG _RUNindex;
- PIXEL* _previousLine; // previous line ptr
-@@ -309,7 +309,7 @@ CTable InitTable(LONG k)
- CTable table;
- short nerr;
- for (nerr = 0; ; nerr++)
-- {
-+ {
- // Q is not used when k != 0
- LONG merrval = GetMappedErrVal(nerr);//, k, -1);
- OFPair<LONG, LONG> paircode = CreateEncodedValue(k, merrval);
-@@ -321,7 +321,7 @@ CTable InitTable(LONG k)
- }
-
- for (nerr = -1; ; nerr--)
-- {
-+ {
- // Q is not used when k != 0
- LONG merrval = GetMappedErrVal(nerr);//, k, -1);
- OFPair<LONG, LONG> paircode = CreateEncodedValue(k, merrval);
-@@ -364,7 +364,7 @@ inlinehint void JlsCodec<TRAITS,STRATEGY>::EncodeMappedValue(LONG k, LONG mapped
- if (highbits + 1 > 31)
- {
- STRATEGY::AppendToBitStream(0, highbits / 2);
-- highbits = highbits - highbits / 2;
-+ highbits = highbits - highbits / 2;
- }
- STRATEGY::AppendToBitStream(1, highbits + 1);
- STRATEGY::AppendToBitStream((mappedError & ((1 << k) - 1)), k);
-@@ -374,11 +374,11 @@ inlinehint void JlsCodec<TRAITS,STRATEGY>::EncodeMappedValue(LONG k, LONG mapped
- if (limit - traits.qbpp > 31)
- {
- STRATEGY::AppendToBitStream(0, 31);
-- STRATEGY::AppendToBitStream(1, limit - traits.qbpp - 31);
-+ STRATEGY::AppendToBitStream(1, limit - traits.qbpp - 31);
- }
- else
- {
-- STRATEGY::AppendToBitStream(1, limit - traits.qbpp);
-+ STRATEGY::AppendToBitStream(1, limit - traits.qbpp);
- }
- STRATEGY::AppendToBitStream((mappedError - 1) & ((1 << traits.qbpp) - 1), traits.qbpp);
- }
-@@ -389,33 +389,33 @@ inlinehint void JlsCodec<TRAITS,STRATEGY>::EncodeMappedValue(LONG k, LONG mapped
- template<class TRAITS, class STRATEGY>
- void JlsCodec<TRAITS,STRATEGY>::InitQuantizationLUT()
- {
-- // for lossless mode with default parameters, we have precomputed te luts for bitcounts 8,10,12 and 16
-+ // for lossless mode with default parameters, we have precomputed te luts for bitcounts 8,10,12 and 16
- if (traits.NEAR == 0 && traits.MAXVAL == (1 << traits.bpp) - 1)
- {
- JlsCustomParameters presets = ComputeDefault(traits.MAXVAL, traits.NEAR);
- if (presets.T1 == T1 && presets.T2 == T2 && presets.T3 == T3)
- {
-- if (traits.bpp == 8)
-+ if (traits.bpp == 8)
- {
-- _pquant = &rgquant8Ll[rgquant8Ll.size() / 2 ];
-+ _pquant = &rgquant8Ll[rgquant8Ll.size() / 2 ];
- return;
- }
-- if (traits.bpp == 10)
-+ if (traits.bpp == 10)
- {
-- _pquant = &rgquant10Ll[rgquant10Ll.size() / 2 ];
-+ _pquant = &rgquant10Ll[rgquant10Ll.size() / 2 ];
- return;
-- }
-- if (traits.bpp == 12)
-+ }
-+ if (traits.bpp == 12)
- {
-- _pquant = &rgquant12Ll[rgquant12Ll.size() / 2 ];
-+ _pquant = &rgquant12Ll[rgquant12Ll.size() / 2 ];
- return;
-- }
-- if (traits.bpp == 16)
-+ }
-+ if (traits.bpp == 16)
- {
-- _pquant = &rgquant16Ll[rgquant16Ll.size() / 2 ];
-+ _pquant = &rgquant16Ll[rgquant16Ll.size() / 2 ];
- return;
-- }
-- }
-+ }
-+ }
- }
-
- LONG RANGE = 1 << traits.bpp;
-@@ -453,7 +453,7 @@ template<class TRAITS, class STRATEGY>
- LONG JlsCodec<TRAITS,STRATEGY>::DecodeRIError(CContextRunMode& ctx)
- {
- LONG k = ctx.GetGolomb();
-- LONG EMErrval = DecodeValue(k, traits.LIMIT - J[_RUNindex]-1, traits.qbpp);
-+ LONG EMErrval = DecodeValue(k, traits.LIMIT - J[_RUNindex]-1, traits.qbpp);
- LONG Errval = ctx.ComputeErrVal(EMErrval + ctx._nRItype, k);
- ctx.UpdateVariables(Errval, EMErrval);
- return Errval;
-@@ -466,7 +466,7 @@ void JlsCodec<TRAITS,STRATEGY>::EncodeRIError(CContextRunMode& ctx, LONG Errval)
- {
- LONG k = ctx.GetGolomb();
- bool map = ctx.ComputeMap(Errval, k);
-- LONG EMErrval = 2 * ABS(Errval) - ctx._nRItype - map;
-+ LONG EMErrval = 2 * ABS(Errval) - ctx._nRItype - map;
-
- ASSERT(Errval == ctx.ComputeErrVal(EMErrval + ctx._nRItype, k));
- EncodeMappedValue(k, EMErrval, traits.LIMIT-J[_RUNindex]-1);
-@@ -476,7 +476,7 @@ void JlsCodec<TRAITS,STRATEGY>::EncodeRIError(CContextRunMode& ctx, LONG Errval)
-
- template<class TRAITS, class STRATEGY>
- Triplet<OFTypename TRAITS::SAMPLE> JlsCodec<TRAITS,STRATEGY>::DecodeRIPixel(Triplet<SAMPLE> Ra, Triplet<SAMPLE> Rb)
--{
-+{
- LONG Errval1 = DecodeRIError(_contextRunmode[0]);
- LONG Errval2 = DecodeRIError(_contextRunmode[0]);
- LONG Errval3 = DecodeRIError(_contextRunmode[0]);
-@@ -513,18 +513,18 @@ Triplet<OFTypename TRAITS::SAMPLE> JlsCodec<TRAITS,STRATEGY>::EncodeRIPixel(Trip
- template<class TRAITS, class STRATEGY>
- void JlsCodec<TRAITS,STRATEGY>::EncodeRunPixels(LONG runLength, bool endOfLine)
- {
-- while (runLength >= LONG(1 << J[_RUNindex]))
-+ while (runLength >= LONG(1 << J[_RUNindex]))
- {
- STRATEGY::AppendOnesToBitStream(1);
- runLength = runLength - LONG(1 << J[_RUNindex]);
- IncrementRunIndex();
- }
-
-- if (endOfLine)
-+ if (endOfLine)
- {
-- if (runLength != 0)
-+ if (runLength != 0)
- {
-- STRATEGY::AppendOnesToBitStream(1);
-+ STRATEGY::AppendOnesToBitStream(1);
- }
- }
- else
-@@ -556,7 +556,7 @@ LONG JlsCodec<TRAITS,STRATEGY>::DecodeRunPixels(PIXEL Ra, PIXEL* startPos, LONG
-
- if (index != cpixelMac)
- {
-- // incomplete run
-+ // incomplete run
- index += (J[_RUNindex] > 0) ? STRATEGY::ReadValue(J[_RUNindex]) : 0;
- }
-
-@@ -566,7 +566,7 @@ LONG JlsCodec<TRAITS,STRATEGY>::DecodeRunPixels(PIXEL Ra, PIXEL* startPos, LONG
- for (LONG i = 0; i < index; ++i)
- {
- startPos[i] = Ra;
-- }
-+ }
-
- return index;
- }
-@@ -582,7 +582,7 @@ LONG JlsCodec<TRAITS,STRATEGY>::DoRunMode(LONG index, EncoderStrategy*)
-
- LONG runLength = 0;
-
-- while (traits.IsNear(ptypeCurX[runLength],Ra))
-+ while (traits.IsNear(ptypeCurX[runLength],Ra))
- {
- ptypeCurX[runLength] = Ra;
- runLength++;
-@@ -629,14 +629,24 @@ void JlsCodec<TRAITS,STRATEGY>::DoLine(SAMPLE*)
- LONG index = 0;
- LONG Rb = _previousLine[index-1];
- LONG Rd = _previousLine[index];
-+ LONG RANGE_UPPER = 1 << traits.bpp;
-+ LONG RANGE_LOWER = - RANGE_UPPER;
-
- while(index < _width)
-- {
-+ {
- LONG Ra = _currentLine[index -1];
- LONG Rc = Rb;
- Rb = Rd;
- Rd = _previousLine[index + 1];
-
-+ // make sure that values are not out of range
-+ if ( (Rd - Rb < RANGE_LOWER) || (Rd - Rb > RANGE_UPPER)
-+ || (Rb - Rc < RANGE_LOWER) || (Rb - Rc > RANGE_UPPER)
-+ || (Rc - Ra < RANGE_LOWER) || (Rc - Ra > RANGE_UPPER))
-+ {
-+ throw JlsException(InvalidCompressedData);
-+ }
-+
- LONG Qs = ComputeContextID(QuantizeGratient(Rd - Rb), QuantizeGratient(Rb - Rc), QuantizeGratient(Rc - Ra));
-
- if (Qs != 0)
-@@ -648,8 +658,8 @@ void JlsCodec<TRAITS,STRATEGY>::DoLine(SAMPLE*)
- {
- index += DoRunMode(index, (STRATEGY*)(NULL));
- Rb = _previousLine[index-1];
-- Rd = _previousLine[index];
-- }
-+ Rd = _previousLine[index];
-+ }
- }
- }
-
-@@ -661,7 +671,7 @@ void JlsCodec<TRAITS,STRATEGY>::DoLine(Triplet<SAMPLE>*)
- {
- LONG index = 0;
- while(index < _width)
-- {
-+ {
- Triplet<SAMPLE> Ra = _currentLine[index -1];
- Triplet<SAMPLE> Rc = _previousLine[index-1];
- Triplet<SAMPLE> Rb = _previousLine[index];
-@@ -671,7 +681,7 @@ void JlsCodec<TRAITS,STRATEGY>::DoLine(Triplet<SAMPLE>*)
- LONG Qs2 = ComputeContextID(QuantizeGratient(Rd.v2 - Rb.v2), QuantizeGratient(Rb.v2 - Rc.v2), QuantizeGratient(Rc.v2 - Ra.v2));
- LONG Qs3 = ComputeContextID(QuantizeGratient(Rd.v3 - Rb.v3), QuantizeGratient(Rb.v3 - Rc.v3), QuantizeGratient(Rc.v3 - Ra.v3));
-
--
-+
- if (Qs1 == 0 && Qs2 == 0 && Qs3 == 0)
- {
- index += DoRunMode(index, (STRATEGY*)(NULL));
-@@ -684,19 +694,19 @@ void JlsCodec<TRAITS,STRATEGY>::DoLine(Triplet<SAMPLE>*)
- Rx.v3 = DoRegular(Qs3, _currentLine[index].v3, GetPredictedValue(Ra.v3, Rb.v3, Rc.v3), (STRATEGY*)(NULL));
- _currentLine[index] = Rx;
- index++;
-- }
-+ }
- }
- }
-
-
--// DoScan: Encodes or decodes a scan.
-+// DoScan: Encodes or decodes a scan.
- // In ILV_SAMPLE mode, multiple components are handled in DoLine
- // In ILV_LINE mode, a call do DoLine is made for every component
--// In ILV_NONE mode, DoScan is called for each component
-+// In ILV_NONE mode, DoScan is called for each component
-
- template<class TRAITS, class STRATEGY>
- void JlsCodec<TRAITS,STRATEGY>::DoScan(BYTE **ptr, size_t *size, size_t offset)
--{
-+{
- _width = Info().width;
-
- STRATEGY::Init(ptr, size, offset);
-@@ -706,11 +716,11 @@ void JlsCodec<TRAITS,STRATEGY>::DoScan(BYTE **ptr, size_t *size, size_t offset)
-
- OFVector<PIXEL> vectmp(2 * components * pixelstride);
- OFVector<LONG> rgRUNindex(components);
--
-+
- for (LONG line = 0; line < Info().height; ++line)
- {
-- _previousLine = &vectmp[1];
-- _currentLine = &vectmp[1 + components * pixelstride];
-+ _previousLine = &vectmp[1];
-+ _currentLine = &vectmp[1 + components * pixelstride];
- if ((line & 1) == 1)
- {
- PIXEL *tmp = _previousLine;
-@@ -724,17 +734,17 @@ void JlsCodec<TRAITS,STRATEGY>::DoScan(BYTE **ptr, size_t *size, size_t offset)
- for (int component = 0; component < components; ++component)
- {
- _RUNindex = rgRUNindex[component];
--
-+
- // initialize edge pixels used for prediction
- _previousLine[_width] = _previousLine[_width - 1];
- _currentLine[-1] = _previousLine[0];
- DoLine((PIXEL*) NULL); // dummy arg for overload resolution
--
-+
- rgRUNindex[component] = _RUNindex;
- _previousLine += pixelstride;
- _currentLine += pixelstride;
- }
--
-+
- if (_rect.Y <= line && line < _rect.Y + _rect.Height)
- {
- STRATEGY::OnLineEnd(_rect.Width, _currentLine + _rect.X - (components * pixelstride), pixelstride);
-@@ -754,7 +764,7 @@ ProcessLine* JlsCodec<TRAITS,STRATEGY>::CreateProcess(void* pvoidOut)
- return new PostProcesSingleComponent(pvoidOut, Info(), sizeof(typename TRAITS::PIXEL));
-
- if (Info().colorTransform == 0)
-- return new ProcessTransformed<TransformNone<OFTypename TRAITS::SAMPLE> >(pvoidOut, Info(), TransformNone<SAMPLE>());
-+ return new ProcessTransformed<TransformNone<OFTypename TRAITS::SAMPLE> >(pvoidOut, Info(), TransformNone<SAMPLE>());
-
- if (Info().bitspersample == sizeof(SAMPLE)*8)
- {
-@@ -765,7 +775,7 @@ ProcessLine* JlsCodec<TRAITS,STRATEGY>::CreateProcess(void* pvoidOut)
- case COLORXFORM_HP3 : return new ProcessTransformed<TransformHp3<SAMPLE> >(pvoidOut, Info(), TransformHp3<SAMPLE>()); break;
- default: throw JlsException(UnsupportedColorTransform);
- }
-- }
-+ }
- else if (Info().bitspersample > 8)
- {
- int shift = 16 - Info().bitspersample;
-@@ -796,7 +806,7 @@ size_t JlsCodec<TRAITS,STRATEGY>::EncodeScan(const void* rawData, BYTE **ptr, si
- }
-
- DoScan(ptr, size, offset);
--
-+
- return STRATEGY::GetLength();
-
- }
-@@ -827,7 +837,7 @@ size_t JlsCodec<TRAITS,STRATEGY>::DecodeScan(void* rawData, const JlsRect& rect,
- _rect = rect;
-
- DoScan(ptr, size, offset + readBytes);
--
-+
- return STRATEGY::GetCurBytePos() - (*ptr + offset);
- }
-
+++ /dev/null
-Description: Fixed issue with invalid "YBR_FULL" DICOM images.
- Fixed an issue when processing an invalid DICOM image with a Photometric
- Interpretation of "YBR_FULL" and a Planar Configuration of "1" where
- the number of pixels stored does not match the expected number of pixels
- (much too less). Now, the pixel data of such an image is not processed
- at all, but an empty image (black pixels) is created instead. The user
- is warned about this by an appropriate log message.
- .
- Thanks to Ding zhengzheng <xiaozheng.ding399@gmail.com> for the report
- and the sample file (PoC).
-Author: Joerg Riesmeier <dicom@jriesmeier.com>
-Applied-Upstream: 7ad81d69b19714936e18ea5fc74edaeb9f021ce7
-Reviewed-By: Étienne Mollier <emollier@debian.org>
-Last-Update: 2025-08-15
-
---- dcmtk.orig/dcmimage/include/dcmtk/dcmimage/dicopxt.h
-+++ dcmtk/dcmimage/include/dcmtk/dcmimage/dicopxt.h
-@@ -574,7 +574,11 @@
- {
- /* erase empty part of the buffer (=blacken the background) */
- if (InputCount < Count)
-- OFBitmanipTemplate<T>::zeroMem(Data[j] + InputCount, Count - InputCount);
-+ {
-+ const size_t count = (Count - InputCount);
-+ DCMIMAGE_TRACE("filing empty part of the intermediate pixel data (" << count << " pixels) of plane " << j << " with value = 0");
-+ OFBitmanipTemplate<T>::zeroMem(Data[j] + InputCount, count);
-+ }
- } else {
- DCMIMAGE_DEBUG("cannot allocate memory buffer for 'Data[" << j << "]' in DiColorPixelTemplate::Init()");
- result = 0; // at least one buffer could not be allocated!
---- dcmtk.orig/dcmimage/include/dcmtk/dcmimage/diybrpxt.h
-+++ dcmtk/dcmimage/include/dcmtk/dcmimage/diybrpxt.h
-@@ -1,6 +1,6 @@
- /*
- *
-- * Copyright (C) 1998-2016, OFFIS e.V.
-+ * Copyright (C) 1998-2025, OFFIS e.V.
- * All rights reserved. See COPYRIGHT file for details.
- *
- * This software and supporting documentation were developed by
-@@ -24,6 +24,7 @@
- #define DIYBRPXT_H
-
- #include "dcmtk/config/osconfig.h"
-+#include "dcmtk/ofstd/ofbmanip.h"
-
- #include "dcmtk/dcmimage/dicopxt.h"
- #include "dcmtk/dcmimgle/diinpx.h" /* gcc 3.4 needs this */
-@@ -90,179 +91,189 @@
- // use the number of input pixels derived from the length of the 'PixelData'
- // attribute), but not more than the size of the intermediate buffer
- const unsigned long count = (this->InputCount < this->Count) ? this->InputCount : this->Count;
-- if (rgb) /* convert to RGB model */
-+ // make sure that there is sufficient input data (for planar pixel data)
-+ if (!this->PlanarConfiguration || (count >= planeSize * 3 /* number of planes */))
- {
-- T2 *r = this->Data[0];
-- T2 *g = this->Data[1];
-- T2 *b = this->Data[2];
-- const T2 maxvalue = OFstatic_cast(T2, DicomImageClass::maxval(bits));
-- DiPixelRepresentationTemplate<T1> rep;
-- if (bits == 8 && !rep.isSigned()) // only for unsigned 8 bit
-+ if (rgb) /* convert to RGB model */
- {
-- Sint16 rcr_tab[256];
-- Sint16 gcb_tab[256];
-- Sint16 gcr_tab[256];
-- Sint16 bcb_tab[256];
-- const double r_const = 0.7010 * OFstatic_cast(double, maxvalue);
-- const double g_const = 0.5291 * OFstatic_cast(double, maxvalue);
-- const double b_const = 0.8859 * OFstatic_cast(double, maxvalue);
-- unsigned long l;
-- for (l = 0; l < 256; ++l)
-+ T2 *r = this->Data[0];
-+ T2 *g = this->Data[1];
-+ T2 *b = this->Data[2];
-+ const T2 maxvalue = OFstatic_cast(T2, DicomImageClass::maxval(bits));
-+ DiPixelRepresentationTemplate<T1> rep;
-+ if (bits == 8 && !rep.isSigned()) // only for unsigned 8 bit
- {
-- rcr_tab[l] = OFstatic_cast(Sint16, 1.4020 * OFstatic_cast(double, l) - r_const);
-- gcb_tab[l] = OFstatic_cast(Sint16, 0.3441 * OFstatic_cast(double, l));
-- gcr_tab[l] = OFstatic_cast(Sint16, 0.7141 * OFstatic_cast(double, l) - g_const);
-- bcb_tab[l] = OFstatic_cast(Sint16, 1.7720 * OFstatic_cast(double, l) - b_const);
-- }
-- Sint32 sr;
-- Sint32 sg;
-- Sint32 sb;
-- if (this->PlanarConfiguration)
-- {
--/*
-- const T1 *y = pixel;
-- const T1 *cb = y + this->InputCount;
-- const T1 *cr = cb + this->InputCount;
-- for (i = count; i != 0; --i, ++y, ++cb, ++cr)
-+ Sint16 rcr_tab[256];
-+ Sint16 gcb_tab[256];
-+ Sint16 gcr_tab[256];
-+ Sint16 bcb_tab[256];
-+ const double r_const = 0.7010 * OFstatic_cast(double, maxvalue);
-+ const double g_const = 0.5291 * OFstatic_cast(double, maxvalue);
-+ const double b_const = 0.8859 * OFstatic_cast(double, maxvalue);
-+ unsigned long l;
-+ for (l = 0; l < 256; ++l)
- {
-- sr = OFstatic_cast(Sint32, *y) + OFstatic_cast(Sint32, rcr_tab[*cr]);
-- sg = OFstatic_cast(Sint32, *y) - OFstatic_cast(Sint32, gcb_tab[*cb]) - OFstatic_cast(Sint32, gcr_tab[*cr]);
-- sb = OFstatic_cast(Sint32, *y) + OFstatic_cast(Sint32, bcb_tab[*cb]);
-- *(r++) = (sr < 0) ? 0 : (sr > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sr);
-- *(g++) = (sg < 0) ? 0 : (sg > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sg);
-- *(b++) = (sb < 0) ? 0 : (sb > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sb);
-+ rcr_tab[l] = OFstatic_cast(Sint16, 1.4020 * OFstatic_cast(double, l) - r_const);
-+ gcb_tab[l] = OFstatic_cast(Sint16, 0.3441 * OFstatic_cast(double, l));
-+ gcr_tab[l] = OFstatic_cast(Sint16, 0.7141 * OFstatic_cast(double, l) - g_const);
-+ bcb_tab[l] = OFstatic_cast(Sint16, 1.7720 * OFstatic_cast(double, l) - b_const);
- }
-+ Sint32 sr;
-+ Sint32 sg;
-+ Sint32 sb;
-+ if (this->PlanarConfiguration)
-+ {
-+/*
-+ const T1 *y = pixel;
-+ const T1 *cb = y + this->InputCount;
-+ const T1 *cr = cb + this->InputCount;
-+ for (i = count; i != 0; --i, ++y, ++cb, ++cr)
-+ {
-+ sr = OFstatic_cast(Sint32, *y) + OFstatic_cast(Sint32, rcr_tab[*cr]);
-+ sg = OFstatic_cast(Sint32, *y) - OFstatic_cast(Sint32, gcb_tab[*cb]) - OFstatic_cast(Sint32, gcr_tab[*cr]);
-+ sb = OFstatic_cast(Sint32, *y) + OFstatic_cast(Sint32, bcb_tab[*cb]);
-+ *(r++) = (sr < 0) ? 0 : (sr > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sr);
-+ *(g++) = (sg < 0) ? 0 : (sg > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sg);
-+ *(b++) = (sb < 0) ? 0 : (sb > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sb);
-+ }
- */
-- const T1 *y = pixel;
-- const T1 *cb = y + planeSize;
-- const T1 *cr = cb + planeSize;
-- unsigned long i = count;
-- while (i != 0)
-+ const T1 *y = pixel;
-+ const T1 *cb = y + planeSize;
-+ const T1 *cr = cb + planeSize;
-+ unsigned long i = count;
-+ while (i != 0)
-+ {
-+ /* convert a single frame */
-+ for (l = planeSize; (l != 0) && (i != 0); --l, --i, ++y, ++cb, ++cr)
-+ {
-+ sr = OFstatic_cast(Sint32, *y) + OFstatic_cast(Sint32, rcr_tab[*cr]);
-+ sg = OFstatic_cast(Sint32, *y) - OFstatic_cast(Sint32, gcb_tab[*cb]) - OFstatic_cast(Sint32, gcr_tab[*cr]);
-+ sb = OFstatic_cast(Sint32, *y) + OFstatic_cast(Sint32, bcb_tab[*cb]);
-+ *(r++) = (sr < 0) ? 0 : (sr > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sr);
-+ *(g++) = (sg < 0) ? 0 : (sg > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sg);
-+ *(b++) = (sb < 0) ? 0 : (sb > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sb);
-+ }
-+ /* jump to next frame start (skip 2 planes) */
-+ y += 2 * planeSize;
-+ cb += 2 * planeSize;
-+ cr += 2 * planeSize;
-+ }
-+ }
-+ else
- {
-- /* convert a single frame */
-- for (l = planeSize; (l != 0) && (i != 0); --l, --i, ++y, ++cb, ++cr)
-+ const T1 *p = pixel;
-+ T1 y;
-+ T1 cb;
-+ T1 cr;
-+ unsigned long i;
-+ for (i = count; i != 0; --i)
- {
-- sr = OFstatic_cast(Sint32, *y) + OFstatic_cast(Sint32, rcr_tab[OFstatic_cast(Uint32, *cr)]);
-- sg = OFstatic_cast(Sint32, *y) - OFstatic_cast(Sint32, gcb_tab[OFstatic_cast(Uint32, *cb)]) - OFstatic_cast(Sint32, gcr_tab[OFstatic_cast(Uint32, *cr)]);
-- sb = OFstatic_cast(Sint32, *y) + OFstatic_cast(Sint32, bcb_tab[OFstatic_cast(Uint32, *cb)]);
-+ y = *(p++);
-+ cb = *(p++);
-+ cr = *(p++);
-+ sr = OFstatic_cast(Sint32, y) + OFstatic_cast(Sint32, rcr_tab[cr]);
-+ sg = OFstatic_cast(Sint32, y) - OFstatic_cast(Sint32, gcb_tab[cb]) - OFstatic_cast(Sint32, gcr_tab[cr]);
-+ sb = OFstatic_cast(Sint32, y) + OFstatic_cast(Sint32, bcb_tab[cb]);
- *(r++) = (sr < 0) ? 0 : (sr > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sr);
- *(g++) = (sg < 0) ? 0 : (sg > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sg);
- *(b++) = (sb < 0) ? 0 : (sb > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sb);
- }
-- /* jump to next frame start (skip 2 planes) */
-- y += 2 * planeSize;
-- cb += 2 * planeSize;
-- cr += 2 * planeSize;
- }
- }
- else
- {
-- const T1 *p = pixel;
-- T1 y;
-- T1 cb;
-- T1 cr;
-- unsigned long i;
-- for (i = count; i != 0; --i)
-+ if (this->PlanarConfiguration)
-+ {
-+/*
-+ const T1 *y = pixel;
-+ const T1 *cb = y + this->InputCount;
-+ const T1 *cr = cb + this->InputCount;
-+ for (i = count; i != 0; --i)
-+ convertValue(*(r++), *(g++), *(b++), removeSign(*(y++), offset), removeSign(*(cb++), offset),
-+ removeSign(*(cr++), offset), maxvalue);
-+*/
-+ unsigned long l;
-+ unsigned long i = count;
-+ const T1 *y = pixel;
-+ const T1 *cb = y + planeSize;
-+ const T1 *cr = cb + planeSize;
-+ while (i != 0)
-+ {
-+ /* convert a single frame */
-+ for (l = planeSize; (l != 0) && (i != 0); --l, --i)
-+ {
-+ convertValue(*(r++), *(g++), *(b++), removeSign(*(y++), offset), removeSign(*(cb++), offset),
-+ removeSign(*(cr++), offset), maxvalue);
-+ }
-+ /* jump to next frame start (skip 2 planes) */
-+ y += 2 * planeSize;
-+ cb += 2 * planeSize;
-+ cr += 2 * planeSize;
-+ }
-+ }
-+ else
- {
-- y = *(p++);
-- cb = *(p++);
-- cr = *(p++);
-- sr = OFstatic_cast(Sint32, y) + OFstatic_cast(Sint32, rcr_tab[OFstatic_cast(Uint32, cr)]);
-- sg = OFstatic_cast(Sint32, y) - OFstatic_cast(Sint32, gcb_tab[OFstatic_cast(Uint32, cb)]) - OFstatic_cast(Sint32, gcr_tab[OFstatic_cast(Uint32, cr)]);
-- sb = OFstatic_cast(Sint32, y) + OFstatic_cast(Sint32, bcb_tab[OFstatic_cast(Uint32, cb)]);
-- *(r++) = (sr < 0) ? 0 : (sr > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sr);
-- *(g++) = (sg < 0) ? 0 : (sg > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sg);
-- *(b++) = (sb < 0) ? 0 : (sb > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sb);
-+ const T1 *p = pixel;
-+ T2 y;
-+ T2 cb;
-+ T2 cr;
-+ unsigned long i;
-+ for (i = count; i != 0; --i)
-+ {
-+ y = removeSign(*(p++), offset);
-+ cb = removeSign(*(p++), offset);
-+ cr = removeSign(*(p++), offset);
-+ convertValue(*(r++), *(g++), *(b++), y, cb, cr, maxvalue);
-+ }
- }
- }
-- }
-- else
-- {
-+ } else { /* retain YCbCr model */
-+ const T1 *p = pixel;
- if (this->PlanarConfiguration)
- {
--/*
-- const T1 *y = pixel;
-- const T1 *cb = y + this->InputCount;
-- const T1 *cr = cb + this->InputCount;
-- for (i = count; i != 0; --i)
-- convertValue(*(r++), *(g++), *(b++), removeSign(*(y++), offset), removeSign(*(cb++), offset),
-- removeSign(*(cr++), offset), maxvalue);
--*/
-+ /*
-+ T2 *q;
-+ // number of pixels to be skipped (only applicable if 'PixelData' contains more
-+ // pixels than expected)
-+ const unsigned long skip = (this->InputCount > this->Count) ? (this->InputCount - this->Count) : 0;
-+ for (int j = 0; j < 3; ++j)
-+ {
-+ q = this->Data[j];
-+ for (i = count; i != 0; --i)
-+ *(q++) = removeSign(*(p++), offset);
-+ // skip to beginning of next plane
-+ p += skip;
-+ }
-+ */
- unsigned long l;
-- unsigned long i = count;
-- const T1 *y = pixel;
-- const T1 *cb = y + planeSize;
-- const T1 *cr = cb + planeSize;
-- while (i != 0)
-+ unsigned long i = 0;
-+ while (i < count)
- {
-- /* convert a single frame */
-- for (l = planeSize; (l != 0) && (i != 0); --l, --i)
-+ /* store current pixel index */
-+ const unsigned long iStart = i;
-+ for (int j = 0; j < 3; ++j)
- {
-- convertValue(*(r++), *(g++), *(b++), removeSign(*(y++), offset), removeSign(*(cb++), offset),
-- removeSign(*(cr++), offset), maxvalue);
-+ /* convert a single plane */
-+ for (l = planeSize, i = iStart; (l != 0) && (i < count); --l, ++i)
-+ this->Data[j][i] = removeSign(*(p++), offset);
- }
-- /* jump to next frame start (skip 2 planes) */
-- y += 2 * planeSize;
-- cb += 2 * planeSize;
-- cr += 2 * planeSize;
- }
- }
- else
- {
-- const T1 *p = pixel;
-- T2 y;
-- T2 cb;
-- T2 cr;
-+ int j;
- unsigned long i;
-- for (i = count; i != 0; --i)
-- {
-- y = removeSign(*(p++), offset);
-- cb = removeSign(*(p++), offset);
-- cr = removeSign(*(p++), offset);
-- convertValue(*(r++), *(g++), *(b++), y, cb, cr, maxvalue);
-- }
-+ for (i = 0; i < count; ++i) /* for all pixel ... */
-+ for (j = 0; j < 3; ++j)
-+ this->Data[j][i] = removeSign(*(p++), offset); /* ... copy planes */
- }
- }
-- } else { /* retain YCbCr model */
-- const T1 *p = pixel;
-- if (this->PlanarConfiguration)
-- {
--/*
-- T2 *q;
-- // number of pixels to be skipped (only applicable if 'PixelData' contains more
-- // pixels than expected)
-- const unsigned long skip = (this->InputCount > this->Count) ? (this->InputCount - this->Count) : 0;
-- for (int j = 0; j < 3; ++j)
-- {
-- q = this->Data[j];
-- for (i = count; i != 0; --i)
-- *(q++) = removeSign(*(p++), offset);
-- // skip to beginning of next plane
-- p += skip;
-- }
--*/
-- unsigned long l;
-- unsigned long i = 0;
-- while (i < count)
-- {
-- /* store current pixel index */
-- const unsigned long iStart = i;
-- for (int j = 0; j < 3; ++j)
-- {
-- /* convert a single plane */
-- for (l = planeSize, i = iStart; (l != 0) && (i < count); --l, ++i)
-- this->Data[j][i] = removeSign(*(p++), offset);
-- }
-- }
-- }
-- else
-- {
-- int j;
-- unsigned long i;
-- for (i = 0; i < count; ++i) /* for all pixel ... */
-- for (j = 0; j < 3; ++j)
-- this->Data[j][i] = removeSign(*(p++), offset); /* ... copy planes */
-- }
-+ } else {
-+ // do not process the input data, as it is too short
-+ DCMIMAGE_WARN("input data is too short, filling the complete image with black pixels");
-+ // erase empty part of the buffer (that has not been "blackened" yet)
-+ for (int j = 0; j < 3; ++j)
-+ OFBitmanipTemplate<T2>::zeroMem(this->Data[j], count);
- }
- }
- }
---- dcmtk.orig/dcmimgle/libsrc/dcmimage.cc
-+++ dcmtk/dcmimgle/libsrc/dcmimage.cc
-@@ -1,6 +1,6 @@
- /*
- *
-- * Copyright (C) 1996-2024, OFFIS e.V.
-+ * Copyright (C) 1996-2025, OFFIS e.V.
- * All rights reserved. See COPYRIGHT file for details.
- *
- * This software and supporting documentation were developed by
-@@ -210,6 +210,7 @@
- *(q++) = c;
- }
- *q = '\0'; // end of C string
-+ DCMIMGLE_DEBUG("filtered version of 'PhotometricInterpretation' = " << OFSTRING_GUARD(cstr));
- while ((pin->Name != NULL) && (strcmp(pin->Name, cstr) != 0))
- ++pin;
- delete[] cstr;
+++ /dev/null
-Description: Fixed issue with commit 7ad81d69b.
- Fixed an issue with recently committed changes that fix a problem with
- invalid YBR_FULL images
-Applied-Upstream: 3de96da6cd66b1af7224561c568bc3de50cd1398
-Author: Joerg Riesmeier <dicom@jriesmeier.com>
-Last-Update: 2025-08-18
-Reviewed-By: Étienne Mollier <emollier@debian.org>
-
-
-diff --git a/dcmimage/include/dcmtk/dcmimage/diybrpxt.h b/dcmimage/include/dcmtk/dcmimage/diybrpxt.h
-index c5415c149..fdaaafc2d 100644
---- a/dcmimage/include/dcmtk/dcmimage/diybrpxt.h
-+++ b/dcmimage/include/dcmtk/dcmimage/diybrpxt.h
-@@ -92,7 +92,7 @@ class DiYBRPixelTemplate
- // attribute), but not more than the size of the intermediate buffer
- const unsigned long count = (this->InputCount < this->Count) ? this->InputCount : this->Count;
- // make sure that there is sufficient input data (for planar pixel data)
-- if (!this->PlanarConfiguration || (count >= planeSize * 3 /* number of planes */))
-+ if (!this->PlanarConfiguration || (count >= planeSize))
- {
- if (rgb) /* convert to RGB model */
- {
#03_datadic_install.patch
07_dont_export_all_executables.patch
remove_version.patch
-0007-CVE-2024-47796.patch
-0008-CVE-2024-52333.patch
-0009-CVE-2025-25475.patch
-0010-CVE-2025-25474.patch
-0011-CVE-2025-25472.patch
-0012-CVE-2025-2357.patch
-0013-CVE-2025-9732.patch
-0014-CVE-2025-9732.patch